package com.wmh.baseservice.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.wmh.baseservice.admin.cache.permission.RoleMenuRepository;
import com.wmh.baseservice.admin.entity.AdRole;
import com.wmh.baseservice.admin.entity.AdRoleMenu;
import com.wmh.baseservice.admin.mapper.AdRoleMenuMapper;
import com.wmh.baseservice.admin.service.AdRoleMenuService;
import com.wmh.baseservice.admin.service.AdRoleService;
import com.wmh.baseservice.admin.tools.enums.AdRoleEnum;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.mybatisplus.methods.CommonServiceImpl;
import com.wmh.baseservice.common.mybatisplus.structure.LambdaQueryWrapperX;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author mmx generator
 * @since 2021-02-03
 */
@Service
@Slf4j
public class AdRoleMenuServiceImpl extends CommonServiceImpl<AdRoleMenuMapper, AdRoleMenu> implements AdRoleMenuService {

    @Resource
    @Lazy
    private AdRoleService adRoleService;

    @Resource
    @Lazy
    private RoleMenuRepository roleMenuRepository;

    @PostConstruct
    private void initCache() {
        log.info("初始化角色与菜单的映射缓存");
        roleMenuRepository.clear();
        List<Long> roleIds = adRoleService.list().stream().map(AdRole::getId).collect(Collectors.toList());
        roleIds.forEach(i -> {
            List<Long> menuIds = baseMapper.selectList(new LambdaQueryWrapperX<AdRoleMenu>()
                            .eq(AdRoleMenu::getRoleId, i))
                    .stream().map(AdRoleMenu::getMenuId).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(menuIds)) {
                roleMenuRepository.setRoleMenu(i, menuIds);
            }
        });
        log.info("角色与菜单的映射缓存缓存完毕");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setMenuIds(Long roleId, List<Long> menuIds) {
        if (AdRoleEnum.SUPER_ADMIN.getId().equals(roleId)){
            throw new ServiceException("无法操作超级管理员权限");
        }
        delete(roleId);
        List<AdRoleMenu> roleMenus = CollUtil.map(menuIds, i -> new AdRoleMenu().setRoleId(roleId).setMenuId(i), true);
        if (CollUtil.isNotEmpty(roleMenus) && !saveBatch(roleMenus)) {
            throw new ServiceException("为角色设置菜单时失败");
        }
        roleMenuRepository.setRoleMenu(roleId, menuIds);
    }

    @Override
    public void delete(Long roleId) {
        baseMapper.delete(new LambdaQueryWrapperX<AdRoleMenu>()
                .eq(AdRoleMenu::getRoleId, roleId));
        roleMenuRepository.del(roleId);
    }

    @Override
    public List<Long> getMenuIds(Long roleId) {
        List<Long> r = roleMenuRepository.get(roleId);
        if (CollUtil.isEmpty(r)) {
            r = CollUtil.map(baseMapper.list(roleId), AdRoleMenu::getMenuId, true);
            roleMenuRepository.setRoleMenu(roleId, r);
        }
        return r;
    }
}
